package com.joelaws.prototype.server;

import java.util.List;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.joelaws.prototype.client.data.Rating;
import com.joelaws.prototype.client.data.User;
import com.joelaws.prototype.client.meeting.ActionInfo;
import com.joelaws.prototype.client.rpc.Dating;
import com.joelaws.prototype.client.util.Create;
import com.joelaws.prototype.server.dao.DAOFactory;

public class DatingImpl extends RemoteServiceServlet implements Dating {

	private static int RETURN_SIZE = 5;

	private static final long serialVersionUID = 1L;

	public List<User> getBrowseUsers(long thisUser, int start) throws Exception {
		System.out.println("getBrowseUsers start " + thisUser + " " + start);
		try {
			User user = DAOFactory.getUserDAO().getUser(thisUser);

			List<User> results = getUnratedUsers(user);

			if (results.size() < RETURN_SIZE) {
				return results;
			} else if (start + RETURN_SIZE >= results.size()) {
				return Create.newList(results.subList(results.size()
						- RETURN_SIZE, results.size()));
			} else {
				return Create.newList(results.subList(start, start
						+ RETURN_SIZE));
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("getBrowseUsers end");
		}
	}

	private List<User> getUnratedUsers(User user) {
		boolean getFemales = true;

		if (user.getNetworkingService() != null
				&& user.getNetworkingDetails() != null)
			getFemales = user.isMale();

		List<User> results = Create.newList();

		for (User otherUser : DAOFactory.getUserDAO().getUsers(getFemales)) {
			if (DAOFactory.getRatingDAO().getRating(user, otherUser) == null) {
				results.add(otherUser);
			}
		}
		return results;
	}

	public Rating getRating(long thisUser, long otherUser) throws Exception {
		System.out.println("getRating start");
		try {
			return DAOFactory.getRatingDAO().getRating(thisUser, otherUser);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("getRating end");
		}
	}

	public List<User> getRatedUsers(long thisUser) throws Exception {
		System.out.println("getRatedUsers start");
		try {
			List<User> users = Create.newList();
			List<Rating> ratings = DAOFactory.getRatingDAO().getFromRatings(
					thisUser);
			if (ratings == null) {
				return users;
			}
			for (Rating rating : ratings) {
				users.add(DAOFactory.getUserDAO().getUser(rating.getRated()));
			}
			return users;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("getRatedUsers end");
		}
	}

	public void rateUser(long thisUser, long ratedUser, short rating)
			throws Exception {
		System.out.println("rateUser start");
		try {
			DAOFactory.getRatingDAO().store(
					new Rating(thisUser, ratedUser, rating));
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("rateUser end");
		}

	}

	public List<User> search(long thisUserID, String searchString)
			throws Exception {
		System.out.println("SearchImpl " + searchString);
		try {
			List<User> filteredUsers = Create.newList();
			User thisUser = DAOFactory.getUserDAO().getUser(thisUserID);

			if (thisUser.getDatingService() == null
					|| thisUser.getNetworkingService() == null) {
				return filteredUsers;
			}

			List<User> users = getUnratedUsers(thisUser);

			for (User user : users) {
				boolean match = false;
				if (user.getNetworkingService() == null
						|| user.getDatingService() == null)
					continue;
				if (user.getFirstName().contains(searchString)
						|| user.getLastName().contains(searchString))
					match = true;
				else if (user.getNetworkingDetails().getDegree().toString()
						.contains(searchString))
					match = true;
				else if (user.getNetworkingDetails().getEmployment().toString()
						.contains(searchString))
					match = true;
				else if (user.getDatingDetails().getEyeColor().toString()
						.contains(searchString))
					match = true;
				else if (user.getDatingDetails().getHairColor().toString()
						.contains(searchString))
					match = true;
				else if (user.getNetworkingDetails().getIncome().toString()
						.contains(searchString))
					match = true;
				else if (user.getNetworkingDetails().getReligion().toString()
						.contains(searchString))
					match = true;

				if (match) {
					filteredUsers.add(user);
				}
			}
			if (filteredUsers.size() < RETURN_SIZE) {
				return filteredUsers;
			} else {
				return Create.newList(filteredUsers.subList(0, RETURN_SIZE));
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("search end");
		}
	}

	public ActionInfo executeAction(long thisUser, long otherUser, String choice)
			throws Exception {
		System.out.println("executeAction start");
		try {
			return MeetingService.getService().executeAction(thisUser,
					otherUser, choice);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("executeAction end");
		}
	}

	public ActionInfo initMeeting(long thisUser, long otherUser)
			throws Exception {
		System.out.println("initMeeting start");
		try {
			return MeetingService.getService().initiateMeeting(thisUser,
					otherUser);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("initMeeting end");
		}
	}

	public List<User> getMeetingUsers(long thisUser) throws Exception {
		System.out.println("getMeetingUsers start");
		try {
			long[] userIDs = MeetingService.getService().getAllMeetings(
					thisUser);
			List<User> users = Create.newList();
			for (long userID : userIDs) {
				users.add(DAOFactory.getUserDAO().getUser(userID));
			}
			return users;
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			System.out.println("getMeetingUsers end");
		}
	}

}
